#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"

char *procname = "parse";
static char *etcpath = "/etc/relate";
/* line number of "etcpath" */
static int line;
LIST_HEAD(entry_head);

struct entry{
	char name[256];
	char *path[254];
	int numaid;
	struct list_head list;
};

static struct entry* getentry(void)
{
	struct entry *e = malloc(sizeof(struct entry));
	memset(e, 0, sizeof(struct entry));
	list_add(&e->list, &entry_head);
	return e;
}

static int name_exist(char *name)
{
	if(!name)
		return 0;
	struct entry *en;
	char *p;
	int i;
	list_for_each_entry_rcu(en, &entry_head, list)
	{
		for(i=0, p=en->path[i]; p!=NULL; p=en->path[++i])
		{
			if (!strcmp(name, p))
				return 1;
		}
	}

	return 0;
}

void parse( FILE *fp, struct entry *en, int index)
{
	struct entry *e;
	int k;
	char buf[256];
	char *p;
	while( (p = fgets(buf, 256, fp)) != NULL )
	{
		++line;
		buf[strlen(buf)-1] = '\0';	// \n -> \0
		/* skip leading blank */
		for (k=0; k<255; ++k)
			if (buf[k]!=' ' || buf[k]!='t')
				break;
		if (buf[k] == '#')
			continue;
		/* if leading with RELATENAME */
		if (!strncmp("RELATENAME", buf+k, 10))
		{
			e = getentry();
			for (k=k+10; k<255; ++k)
				if (buf[k]!='=' && buf[k]!= ' ' && buf[k]!= '\t')
					break;
			strncpy(e->name, buf+k, 245-k);
			parse(fp, e, 0);
			continue;
		}
		/* if leading with NUMAID */
		if (!strncmp("NUMAID", buf+k, 6))
		{
			if (en == NULL)
			{
				fprintf(stderr,"no config RELATENAME of NUMAID, at line: %d", line);
				exit(0);
			}
			for (k=k+6; k<255; ++k)
			{
				if(isdigit(buf[k]) && buf[k] != '\0')
				{
					en->numaid = strtol(buf+k, NULL, 10);
					break;
				}
			}
			return;
		}
		if (en == NULL)
        {
			printf("%s\n", procname);
			continue;
        }
	if (!name_exist(buf))
		en->path[index++] = strdup(buf);
	else
		printf("%s: error on line %d: dumplicated\n", procname, line);
	}
	return;
}

void show_list(void)
{
	struct entry *en;
	char *p;
	int i=0;
	list_for_each_entry_rcu(en, &entry_head, list)
	{
		printf("name:%s\n", en->name);
		for(i=0, p=en->path[i]; p!=NULL; p=en->path[++i])
		{
			printf("path%d: %s\n", i, en->path[i]);
		}
		printf("numa:%d\n", en->numaid);
	}
}

int main(int argc, char **argv)
{
	FILE *fp;
	if ( (fp = fopen(etcpath, "r")) == NULL)
			perror("foepn");
	parse(fp, NULL, 0);
	
//	show_list();
	return 0;
}
